package com.zhang.controller;

import cn.hutool.core.thread.ThreadUtil;
import com.zhang.service.MyService;
import com.zhang.threads.MyTask;
import com.zhang.threads.MyTask1;
import com.zhang.util.RequestHolder;
import com.zhang.util.RequestUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
public class MyController {
    @Autowired
    private MyService myService;
    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping("/invite/{pid}/{sid}")
    private String invite(@PathVariable("pid")String pid,@PathVariable("sid")String sid){
        myService.invite(pid,sid);
        Integer count = myService.countSub(pid);
        return String.valueOf(count);
    }

    @RequestMapping("/count/{pid}")
    private String count(@PathVariable("pid")String pid){
        Integer count = myService.countSub(pid);
        return String.valueOf(count);
    }

    @GetMapping("/getRedis")
    private String getRedis(){
        RedisConnectionFactory connectionFactory = redisTemplate.getConnectionFactory();
        RedisConnection connection = connectionFactory.getConnection();
        Properties infoMap = connection.info();
        System.out.println("已连接客户端的数量（不包括通过从属服务器连接的客户端）: " + infoMap.get("connected_clients"));
        System.out.println("当前连接的客户端当中，最长的输出列表: " + infoMap.get("client_longest_output_list"));
        System.out.println("当前连接的客户端当中，最大输入缓存: " + infoMap.get("client_biggest_input_buf"));
        System.out.println("正在等待阻塞命令（BLPOP、BRPOP、BRPOPLPUSH）的客户端的数量: " + infoMap.get("blocked_clients"));

        System.out.println("Redis 服务器版本: " + infoMap.get("redis_version"));
        System.out.println("Redis 连接数量: " + infoMap.get("connected_clients"));
        System.out.println("Redis 服务器的随机标识符: " + infoMap.get("run_id"));
        System.out.println("Redis 服务器监听的 TCP 端口: " + infoMap.get("tcp_port"));
        System.out.println("Redis 服务器启动以来的秒数: " + infoMap.get("uptime_in_seconds"));
        System.out.println("Redis 服务器启动以来的天数: " + infoMap.get("uptime_in_days"));
        System.out.println("Redis 分配的内存总量（字节）: " + infoMap.get("used_memory"));
        System.out.println("Redis 分配的内存总量（人类可读格式）: " + infoMap.get("used_memory_human"));
        System.out.println("Redis 已分配的内存总量（常驻集大小）（字节）: " + infoMap.get("used_memory_rss"));
        System.out.println("Redis 已分配的内存总量（常驻集大小）（人类可读格式）: " + infoMap.get("used_memory_rss_human"));
        System.out.println("Redis 的内存消耗峰值（字节）: " + infoMap.get("used_memory_peak"));
        System.out.println("Redis 的内存消耗峰值（人类可读格式）: " + infoMap.get("used_memory_peak_human"));
        System.out.println("Redis 的内存消耗峰值百分比: " + infoMap.get("used_memory_peak_perc"));
        System.out.println("Redis 为了维护数据集的内部机制所需的内存开销: " + infoMap.get("used_memory_overhead"));
        System.out.println("Redis 服务器启动时消耗的内存: " + infoMap.get("used_memory_startup"));
        System.out.println("数据占用的内存大小: " + infoMap.get("used_memory_dataset"));
        System.out.println("数据占用的内存大小的百分比: " + infoMap.get("used_memory_dataset_perc"));
        System.out.println("Redis 实例的最大内存配置: " + infoMap.get("maxmemory"));
        System.out.println("Redis 实例的最大内存配置（人类可读格式）: " + infoMap.get("maxmemory_human"));
        System.out.println("达到 maxmemory 时的淘汰策略: " + infoMap.get("maxmemory_policy"));
        System.out.println("Redis 使用的内存分配器: " + infoMap.get("mem_allocator"));
        System.out.println("服务器角色: " + infoMap.get("role"));
        System.out.println("已连接的从服务器数量: " + infoMap.get("connected_slaves"));
        System.out.println("服务器已接受的连接请求数量: " + infoMap.get("total_connections_received"));
        System.out.println("服务器已执行的命令数量: " + infoMap.get("total_commands_processed"));
        System.out.println("服务器每秒钟执行的命令数量: " + infoMap.get("instantaneous_ops_per_sec"));
        System.out.println("服务器已接受的连接请求数量: " + infoMap.get("total_connections_received"));
        System.out.println("服务器已执行的命令数量: " + infoMap.get("total_commands_processed"));
        System.out.println("服务器每秒钟执行的命令数量: " + infoMap.get("instantaneous_ops_per_sec"));



        return String.valueOf("1");
    }

    @GetMapping("/getRedis2")
    private String getRedis2(String type){
        RedisConnectionFactory connectionFactory = redisTemplate.getConnectionFactory();
        RedisConnection connection = connectionFactory.getConnection();
        Properties infoMap = connection.info(type);

        Set<Object> objects = infoMap.keySet();
        for (Object object : objects) {
            Object o = infoMap.get(object);
            System.out.println("key: " + object + " value: " + o);
        }
        connection.close();
        return String.valueOf("1");
    }


    @GetMapping("/location")
    public String location(){
        myService.getGeo();
        return "success";
    }

    @GetMapping("/excel/{month}")
    public String excel(@PathVariable("month")String month){

        final long l = System.currentTimeMillis();
        String inputFile = "D:\\桌面\\1220数据导入\\GFJC_APP_DEV_HIS_DATA_"+month+".xlsx";
        String outputFolder = "D:\\桌面\\1220数据导入\\GFJC_APP_DEV_HIS_DATA_"+month+"\\output";


        try {
            FileInputStream fis = new FileInputStream(inputFile);
            Workbook workbook = new SXSSFWorkbook(new XSSFWorkbook(fis));
            Sheet sheet = workbook.getSheetAt(0);

            int rowCount = sheet.getLastRowNum();
            int chunkSize = 40000; // 40MB per file
            int totalChunks = (int) Math.ceil((double) rowCount / chunkSize);

            for (int i = 0; i < totalChunks; i++) {
                String outputFileName = outputFolder + File.separator + "output_" + i + ".xlsx";
                FileOutputStream fos = new FileOutputStream(outputFileName);
                Workbook newWorkbook = new SXSSFWorkbook();
                Sheet newSheet = newWorkbook.createSheet();

                for (int j = 0; j < chunkSize; j++) {
                    int rowNum = i * chunkSize + j;
                    if (rowNum >= rowCount) {
                        break;
                    }

                    Row row = sheet.getRow(rowNum);
                    Row newRow = newSheet.createRow(j);
                    for (int k = 0; k < row.getLastCellNum(); k++) {
                        Cell cell = row.getCell(k);
                        Cell newCell = newRow.createCell(k);
                        newCell.setCellValue(cell.getStringCellValue());
                    }
                }

                newWorkbook.write(fos);
                fos.close();
                newWorkbook.close();
            }

            workbook.close();
            fis.close();

            // Compress the output folder
            String zipFileName = outputFolder + File.separator + "output.zip";
            FileOutputStream fos = new FileOutputStream(zipFileName);
            ZipOutputStream zos = new ZipOutputStream(fos);
            File folder = new File(outputFolder);
            for (File file : folder.listFiles()) {
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zos.putNextEntry(zipEntry);
                FileInputStream fis2 = new FileInputStream(file);
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis2.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }
                fis2.close();
                zos.closeEntry();
            }
            zos.close();
            fos.close();

            System.out.println("Excel split and compressed successfully.");
        } catch (IOException e) {
            e.printStackTrace();
        }

        final long l1 = System.currentTimeMillis();

        System.out.println("耗时:"+(l1-l));
        return "success";
    }

    private ThreadPoolExecutor executor = ThreadUtil.newExecutor(5, 20);
    @GetMapping("/testRequest/{id}")
    public String testRequest(@PathVariable("id")String id){

        HttpServletRequest currentRequest = RequestUtils.getCurrentRequest();
        // 创建线程任务

        Callable<Void> task = new MyTask(currentRequest,myService,id);
        FutureTask<Void> futureTask = new FutureTask<Void>(task);
        try {
            // 执行线程任务
            executor.submit(futureTask);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }
    @GetMapping("/testRequest1/{id}")
    public String testRequest1(@PathVariable("id")String id){

        HttpServletRequest currentRequest = RequestUtils.getCurrentRequest();
        // 创建线程任务

        Callable<Void> task = new MyTask1(currentRequest,myService,id);
        FutureTask<Void> futureTask = new FutureTask<Void>(task);
        try {
            // 执行线程任务
            executor.submit(futureTask);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }





}
